/*
 * @Author: Mainul Islam
 */

package edu.uta.cse.randomgraph.graph.property;

public class DeterministicNodeSet {

	public int _n, _k;
	public int _numNodes;
	public int _numEdges;
	public Node _nodes[];
	public boolean _edgeMat[][];
	public int _width, _height;
	
	public DeterministicNodeSet(int k, int n) {
		this._n = n;
		this._k = k;
		_numNodes = (int)Math.pow((double)(k+1), (double)n);
		_numEdges = 0;
		_width = _height = 0;
		_nodes = new Node[_numNodes+1];
		_edgeMat = new boolean[_numNodes+1][_numNodes+1];
	}
	
	public void initRootNode() {
		this._nodes[0] = new Node();
		this._nodes[0].isBaseNode = true;
	}
	
	public void initRootNodePosition(int x, int y) {
		this._nodes[0].X = x;
		this._nodes[0].Y = y;
		this._width = 1;
		this._height = 1;
	}

	
	public void generateNodes(DeterministicNodeSet prev) {
		int i, j, nc;
		int u, v, ind;
		
		// create nodes
		nc = 0;
		for(i=0; i<=_k; i++) {			
			for(j=0; j<prev._numNodes; j++) {
				_nodes[nc] = new Node();
				_nodes[nc].loadNode(prev._nodes[j]);
				
				if(i==0)
					_nodes[nc].isBaseNode = false;
				nc++;
			}
		}

		// create edges
		nc = 0;
		for(i=0; i<=_k; i++) {			
			_numEdges += prev._numEdges;
			for(j=0; j<prev._numNodes; j++) {
				ind = prev._numNodes*i;
				for(u=0; u<prev._numNodes; u++) {
					for(v=0; v<prev._numNodes; v++) {
						if( prev._edgeMat[u][v] ) {
							this._edgeMat[ind+u][ind+v] = true;
							_nodes[ind+u].edgeList.add(ind+v);
						}
					}
				}
				
				nc++;
			}
		}
		addEdgeToBaseNodes();
	}
	
	public void addEdgeToBaseNodes() {
		for(int i=1; i<_numNodes; i++) {
			if(_nodes[i].isBaseNode) {
				_numEdges++;
				this._edgeMat[0][i] = true;	
				this._edgeMat[i][0] = true;	
				_nodes[0].deg++;
				_nodes[i].deg++;
				_nodes[0].edgeList.add(i);
				_nodes[i].edgeList.add(0);
			}
		}
	}
	
	
	public void generateNodeCoordinates(DeterministicNodeSet prev, int widthSpace, int heightSpace) {
		int i, j;
		int distX = 0;
		int nc = 0;
		int startDif = 0;
		
		if(_k%2 == 1)
			startDif = -((prev._width + widthSpace) * (_k/2));
		else 
			startDif = -((prev._width)*(_k/2-1)+prev._width/2+(widthSpace)*(_k/2-1)+widthSpace/2);
		
		for(i=0; i<=_k; i++) {
			if( i!= 0) {
				distX = startDif + ((i-1) * (prev._width + widthSpace)); 
			}

			for(j=0; j<prev._numNodes; j++) {
				if(i == 0) {
					_nodes[nc].X = prev._nodes[j].X;
					_nodes[nc].Y = prev._nodes[j].Y;
				}
				else {
					_nodes[nc].X = prev._nodes[j].X + distX;
					_nodes[nc].Y = prev._nodes[j].Y + prev._height + heightSpace;
				}
				nc++;
			}
		}
		
		this._width = (prev._width * _k) + (widthSpace * (_k-1));
		this._height = prev._height * 2 + heightSpace;
	}


}
